﻿using System.Net.Sockets;
using System.Net;
using HDSmartCommunity.BUS;
using System;
using System.Text;
using System.Threading.Tasks;
using System.Linq;
using System.Threading;
using System.Collections.Generic;
using System.IO.Ports;


namespace HDSmartCommunity.DevicePlatform
{
    public class DataSaveDeviceSerialData
    {
        private static Socket ServerSocket;
        private static byte[] buffer;

        public SerialPort myS0SerialPort_1 = new SerialPort();

        public void Start(int port)
        {
            TcpServerHelper tcpServerHelper = new TcpServerHelper(port);
            tcpServerHelper.Listen();
        }
        public void StartServer(int port)
        {
            try
            {
                ServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                IPEndPoint iPEndPoint = new IPEndPoint(IPAddress.Any, port);
                ServerSocket.Bind(iPEndPoint);

                ServerSocket.Listen(50);
                Task task = new Task(() =>
                {
                    ServerListen();
                });
                task.Start();
            }
            catch
            {
                LogHelper.Log("建立服务端失败");
            }
        }

        /// <summary>
        /// 开始监听
        /// </summary>
        public static void ServerListen()
        {
            Socket ts = ServerSocket.Accept();
            buffer = new byte[1024];
            ts.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(Accept), ts);
        }
        /// <summary>
        /// 接收信息
        /// </summary>
        /// <param name="result"></param>
        public static void Accept(IAsyncResult result)
        {
            Socket ts = (Socket)result.AsyncState;
            int length = ts.EndReceive(result);
            result.AsyncWaitHandle.Close();

            //判断是否断开了，如果断开了，就不接收新数据了
            if (length > 0)
            {
                byte[] data = buffer.Skip(0).Take(length).ToArray();
                string ReceviceMessage = ToHexs(data);
                DataSaveLogHelper.Log(ReceviceMessage);
                //清空数据，重新开始异步接收
                buffer = new byte[buffer.Length];
                ts.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(Accept), ts);
            }
            else
            {
                //断开的话，重新监听是否有新客户端连接过来
                ServerListen();
            }
        }

        public static string ToHexs(byte[] data)
        {
            if (data.Length <= 0) return "";
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < data.Length; i++)
            {
                sb.Append(data[i].ToString("X2") + " ");
            }
            string str = sb.ToString();
            return str;
        }


        /// <summary>
        /// TCP服务端
        /// </summary>
        public class TcpServerHelper : IDisposable
        {
            /// <summary>
            /// 监听套间字
            /// </summary>
            private Socket SocketS { get; set; }
            /// <summary>
            /// 连接池数列
            /// </summary>
            private List<Socket> SocketClients { get; set; }
            /// <summary>
            /// 连接数
            /// </summary>
            public int ConnectCount { get { return SocketClients.Count; } }
            /// <summary>
            /// 是否监听
            /// </summary>
            public bool isListening { get { return SocketS.IsBound; } }
            /// <summary>
            /// 监听的IP
            /// </summary>
            private string Ip { get; set; }
            /// <summary>
            /// 监听的端口
            /// </summary>
            private int Port { get; set; }
            /// <summary>
            /// 监听每次读取字节数
            /// </summary>
            private byte[] Buffer { get; set; }
            /// <summary>
            /// 最大连接数
            /// </summary>
            private int Count { get; set; }
            /// <summary>
            /// 接收消息
            /// </summary>
            public event Action<byte[], int, EndPoint> SocketReceive;
            /// <summary>
            /// 报错事件
            /// </summary>
            public event Action<string, Exception, EndPoint> SocketMessage;
            /// <summary>
            /// 连接事件
            /// </summary>
            public event Action<bool, EndPoint> ConnectEndPoints;
            /// <summary>
            /// /// <summary>
            /// 构造函数
            /// </summary>
            /// <param name="ip">监听的IP</param>
            /// <param name="port">监听的端口</param>
            /// <param name="bufferLength">监听每次读取字节数,默认1MB = 1024 * 1024B</param>
            public TcpServerHelper(int port, int bufferLength = 1024 * 1024, int count = int.MaxValue)
            {
                Port = port;
                Buffer = new byte[bufferLength];
                SocketClients = new List<Socket>();
                Count = count;
            }
            /// <summary>
            /// 开始监听
            /// </summary>
            /// <returns></returns>
            public async Task Listen()
            {
                try
                {
                    //1.0 实例化套接字(IP4寻找协议,流式协议,TCP协议)
                    SocketS = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    //3.0 创建网络端口,包括ip和端口
                    IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, Port);
                    //4.0 绑定套接字
                    SocketS.Bind(endPoint);
                    //5.0 设置最大连接数
                    SocketS.Listen(Count);
                    //6.0 循环遍历连接
                    await Task.Run(() =>
                    {
                        for (; ; )
                        {
                            try
                            {
                                //接收客户端连接
                                Socket SocketClient = SocketS.Accept();
                                //加入连接池数列
                                SocketClients.Add(SocketClient);
                                //连接事件
                                LogHelper.Log("设备连接");
                                //SocketMessage?.Invoke($"{SocketClient.RemoteEndPoint}接入", null, SocketClient.RemoteEndPoint);
                                ConnectEndPoints?.Invoke(true, SocketClient.RemoteEndPoint);
                                //开始监听
                                Thread thread = new Thread(Receive);
                                thread.Start(SocketClient);
                            }
                            catch (SocketException ex)
                            {
                                //SocketMessage?.Invoke("服务监听出错", ex, null);
                            }
                            catch (Exception ex)
                            {
                                //LogHelper.GetInstance().WriteLogEx(ex);
                            }
                        }
                    });
                }
                catch (Exception ex)
                {
                    //SocketMessage?.Invoke("服务监听出错", ex, null);
                }
            }

            /// <summary>
            /// 接收消息
            /// </summary>
            /// <param name="socket">来自客户端的socket</param>
            private void Receive(object SocketClient)
            {
                Socket socketClient = (Socket)SocketClient;
                try
                {
                    for (; ; )
                    {
                        //接收的字节数，当客户端下线时，receiveNumber=0
                        int receiveNumber = socketClient.Receive(Buffer);

                        //判断客户端是否下线，防止客户端下线时，服务端一直接收空消息
                        if (receiveNumber == 0)
                        {
                            throw new SocketException();
                        }
                        else if (receiveNumber > 0)
                        {
                            byte[] data = Buffer.Skip(0).Take(receiveNumber).ToArray();
                            string ReceviceMessage = ToHexs(data);
                            DataSaveLogHelper.Log(ReceviceMessage);
                        }

                        //接收成功事件
                        //SocketReceive(Buffer, receiveNumber, socketClient.RemoteEndPoint);
                    }
                }
                catch (SocketException ex)
                {
                    CloseConnect(socketClient, ex);
                }
                catch (Exception)
                {
                }
            }
            /// <summary>
            /// 断开连接
            /// </summary>
            /// <param name="socket"></param>
            /// <param name="ex"></param>
            private void CloseConnect(Socket socket, SocketException ex)
            {
                //SocketMessage?.Invoke($"{socket.RemoteEndPoint}断开连接", ex, socket.RemoteEndPoint);
                LogHelper.Log("设备断开");
                ConnectEndPoints?.Invoke(false, socket.RemoteEndPoint);
                socket.Close();
                SocketClients.Remove(socket);
            }
            /// <summary>
            /// 释放所有套间字
            /// </summary>
            public void Dispose()
            {
                try
                {
                    SocketS.Close();
                    foreach (Socket socket in SocketClients)
                    {
                        socket.Close();
                    }
                }
                catch { }
            }
            /// <summary>
            /// 析构函数
            /// </summary>
            ~TcpServerHelper()
            {
                Dispose();
            }
        }

    }
}
